/*
 * octal.c
 *
 */
#include "octal.h"
#define VAL_CHAR_CERO 48 // 48 es el valor del caracter 0
// graba en un archivo el valor en octal
// del numero guardado en c.
void grabar(char c, FILE *f){
	int num;
	//si el valor del char esta entre 0 y 7, convierto ese valor en el número correspondiente, sumandole
	//el offset del 0
	if ( (c >= 0) && (c < 8)){
		num = (int)c + VAL_CHAR_CERO;
		fputc(num,f);
	}
}

//convierte el octal en decimal
int convertir(char c, int i){
	int mult;
	//estos if son porque me tira error al hacer pow(8,i)
	if (i == 2){
		mult = 64;
	}
	else if(i == 1){
		mult = 8;
	}
	else {
		mult = 1;
	}
	//el c = 48 es el 0, y el 55 es el 7, entonces solo hace la conversión si c está entre estos valores,
	//sino el archivo no cumple las condiciones
	if ((c>=48) && (c<56)){
		return mult*((int)c - VAL_CHAR_CERO);
	}else{
		return -1;
	}
}

void codificar(FILE *f,FILE *fout, char *delimitador, int len){
	// Resto es el char (paquete de 8 bits) leido del archivo.
    int resto = 0;
    // Cantidad de bits sin procesar en el resto
    int bitsSobrantes = 0;
    int first_read = 0;
    int cantOctales = 0;
    resto = fgetc(f);

    while (!feof(f)) {
        if (bitsSobrantes==0) {
			first_read = 0;
			bitsSobrantes = 8;
		}
		// Comienzo a leer de a tres bits en el resto
		// haciendo corrimientos y los grabo al archivo de salida
        char terna;
        if (first_read == 0){
        	terna = (resto >> 6 );
        	grabar(terna,fout);
        	bitsSobrantes -= 2;
        	first_read = 1;
        }
		while (bitsSobrantes>=3){
			terna = (resto >> (bitsSobrantes-3)) & ~(~0 << (3));
			grabar(terna,fout);
			bitsSobrantes -= 3;
		}

		cantOctales++;
		resto = fgetc(f);
		if(!feof(f)){
			if((cantOctales==len)&&(len!=0)){
				fputs("\n",fout);
				cantOctales = 0;
			}else
				fputs(delimitador,fout);
		}

    }
}

int decodificar(FILE *f,FILE *fout, char *delimitador){
	int bin;
	int i;
	int conv=0;
	int mid = 0;
	int j,k;
	j = strlen(delimitador);


	bin = fgetc(f);
	while (!feof(f)) {
		for (i = 2; i >= 0; i--) {
			conv = convertir(bin, i);
			if (conv == -1)
				return -1;
			mid = mid + conv;
			bin = fgetc(f); //LEE un caracter más, que los 3 del octal
		}
		//convierto en char el decimal que obtuve a partir del octal, y lo escribo en el archivo
		fputc((char) mid, fout);
		mid = 0;

		//si es \n lo salto
		if ((bin == '\n')) {
			bin = fgetc(f);
		} else {
				//salteo el delimitador //Ya leyo el 1er caracter del delimitador en el comentario anterior (o el 1er numero del octal, si no hay delimitador) //le saque el -1 al for, porque comenté el fgetc que le sigue al mismo
				for (k = j; k >= 1; k--) {
					bin = fgetc(f);
				}


		}

	}
	 return 0;

}
